import hashlib
import logging
from datetime import datetime
from typing import Any, List

from fastapi import APIRouter, Depends, Body, HTTPException, Path, UploadFile, File, Form
from fastapi.params import Param
from llama_index.core.base.llms.types import MessageRole
from sqlalchemy import or_, func
from sqlalchemy.orm import Session, Query

from app.core.security import get_current_user
from app.db.session import get_db
from app.llama_index import generateChatTitle
from app.llama_index.session.lifa_session import lifaSessions, LlamaIndexFunctionAgentSession
from app.llama_index.session.livsm_session import livsmSessions, MilvusVectorStoreSession
from app.models import User, KnowledgeBase, Document, Chat, Message
from app.models.ai import AIAgent
from app.models.knowledge import  KnowledgeBaseStatus, DocumentStatus
from app.schemas.base_so import BaseListQo, DelParam, DocumentListQo, ChangeStatusParam, ChangeStatusToDraftParam, \
    DetailParam
from app.schemas.chat import SendMessageParam, AddMessageParam, DeleteMessageParam, ChangeChatAiAgent
from app.schemas.knowledge_base import KnowledgeBaseCreate, KnowledgeBaseUpdate, DocumentUpdate
from app.schemas.result import BaseResult, okResult, errResult, BaseListResult, BaseSksTableResult
from app.services.ai_services import AIService
from app.services.chat_services import getMessagesByChatId
from app.services.file_services import asave_kb_file, FilePathInfo, delete_kb_file, format_file_name_to_read
from app.services.knowledge_services import knowledge_services_change_knowledge_doc_status
from app.utils.str_utils import format_filename

logger = logging.getLogger(__name__)
router = APIRouter()

@router.post("/sendMessage", response_model=BaseResult)
async def send_message(
        db: Session = Depends(get_db),
        param:SendMessageParam=Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    测试接口
    http://127.0.0.1:8880/api/chat/sendMessage
    """
    isNew=False
    chat_id = param.chat_id
    kb:KnowledgeBase=(db.query(KnowledgeBase)
                 # .filter(KnowledgeBase.user_id == current_user.id)
                 ).first()
    # 查询该聊天记录的所有消息
    userMessage = db.query(Message).filter(Message.id == param.problem_id).order_by(Message.id.asc()).first()

    # livsm_session:MilvusVectorStoreSession = livsmSessions.get_session(kb_id=kb.id, dimensions=kb.dimensions, enable_sparse=kb.enable_sparse)
    session:LlamaIndexFunctionAgentSession = lifaSessions.get_session(chat_id=chat_id)
    assistant_msg=session.run(userMessage)

    message=Message(chat_id=chat_id,content=assistant_msg,problem_id=param.problem_id,role=MessageRole.ASSISTANT)
    db.add(message)
    db.commit()
    db.refresh(message)

    resData={
        'chat_id':chat_id,
        'id':message.id,
        'content':assistant_msg,
        'role':message.role,
        'vueVirtualUUID':param.vueVirtualUUID
    }

    return okResult(data=resData)

@router.put("/message/add", response_model=BaseResult)
def add_chat_message(
        *,
        db: Session = Depends(get_db),
        param: AddMessageParam=Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    新增消息
    """
    chat_id = param.chat_id
    if chat_id is None:
        title=generateChatTitle(param.content)
        chat=Chat(user_id=current_user.id,title=title,ai_agent_id=param.ai_agent_id)
        db.add(chat)
        db.commit()
        db.refresh(chat)
        chat_id=chat.id
        logger.info(f"chat added: {chat.title} for user {current_user.id}")
    chat:Chat=(db.query(Chat)
                      .filter(Chat.id == chat_id)
                      ).first()

    message=Message(chat_id=chat_id,content=param.content,role=MessageRole.USER)
    db.add(message)
    db.commit()
    db.refresh(message)
    result={
        'chat_id':chat_id,
        'title':chat.title,
        'id':message.id,
        'content':message.content,
        'role':message.role,
        'vueVirtualUUID':param.vueVirtualUUID,
    }
    return okResult(data=result).json_encoders()


@router.get("/getLastChat", response_model=BaseResult)
def get_last_chat(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
) -> Any:
    """获取最后一次对话"""
    # 查询当前用户的最后一次聊天记录
    last_chat = db.query(Chat).filter(Chat.user_id == current_user.id).order_by(Chat.id.desc()).first()
    
    if not last_chat:
        return okResult()

    # 查询该聊天记录的所有消息
    chat_id=last_chat.id
    messages = getMessagesByChatId(db,chat_id)
    # session:LlamaIndexFunctionAgentSession = lifaSessions.get_session(chat_id=chat_id)
    # session.reset_history(messages)

    # 构建返回结果
    result = {
        'chat_id': last_chat.id,
        'title': last_chat.title,
        'messages': [{
            'id': msg.id,
            'content': msg.content,
            'role': msg.role,
            'created_at': msg.created_at
        } for msg in messages]
    }
    agentInfo=AIService.get_ai_agent_view_info(db,last_chat.ai_agent_id)[0]
    result['agentInfo']={
        "ai_agent_id": last_chat.ai_agent_id,
        "vDesc":agentInfo
    }
    
    return okResult(data=result)

@router.post("/getAIChatDetail", response_model=BaseResult)
def getAIChatDetail(
        db: Session = Depends(get_db),
        param: DetailParam = Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """获取最后一次对话"""
    # 查询当前用户的最后一次聊天记录
    last_chat = db.query(Chat).filter(Chat.id == param.id).first()

    if not last_chat:
        raise HTTPException(status_code=500, detail="找不到会话")

    # 查询该聊天记录的所有消息
    chat_id = last_chat.id
    messages = getMessagesByChatId(db, chat_id)
    # session:LlamaIndexFunctionAgentSession = lifaSessions.get_session(chat_id=chat_id)
    # session.reset_history(messages)

    # 构建返回结果
    result = {
        'chat_id': last_chat.id,
        'title': last_chat.title,
        'messages': [{
            'id': msg.id,
            'content': msg.content,
            'role': msg.role,
            'created_at': msg.created_at
        } for msg in messages]
    }
    agentInfo = AIService.get_ai_agent_view_info(db, last_chat.ai_agent_id)[0]
    result['agentInfo'] = {
        "ai_agent_id": last_chat.ai_agent_id,
        "vDesc": agentInfo
    }

    return okResult(data=result)


@router.post("/history/list", response_model=BaseSksTableResult)
def get_chat_history_list(
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user)
) -> Any:
    total = db.query(func.count(Chat.id)).scalar()
    chat_list = (
        db.query(Chat)
        .order_by(Chat.id.desc())
        .all()
    )
    return BaseSksTableResult(list=chat_list,total=total).json_encoders()

@router.delete("/delete")
async def delete_chat(
        *,
        db: Session = Depends(get_db),
        param: DelParam = Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    Delete chat
    """
    ids = param.ids
    #删除会话的消息,先删除问题的答案
    (db.query(Message) .filter(
        Message.chat_id.in_(ids),Message.problem_id.isnot(None)
    ).delete()
     )
    #再删除问题
    #删除时候增加排序,这样才会先删除答案,避免problem_id的ForeignKey错误
    (db.query(Message)
        .filter(
            Message.chat_id.in_(ids),
        ).delete()
    )
    #删除会话
    query = (
        db.query(Chat)
        .filter(
            Chat.id.in_(ids),
        )
    )
    query.delete()
    db.commit()
    # db.rollback()
    return okResult()


@router.delete("/message/delete")
async def delete_message(
        *,
        db: Session = Depends(get_db),
        param:DeleteMessageParam=Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    Delete knowledge base and all associated resources.
    """
    id=param.id
    _message:Message= (   db.query(Message)
    .filter(
        Message.problem_id==id,
    ).first()
    )
    if _message:
        logger.debug(f"delete message {_message.id}")
        db.delete(_message)
        db.commit()

    _message= (   db.query(Message)
    .filter(
        Message.id==id,
    ).first()
    )
    chat_id=_message.chat_id
    logger.debug(f"delete message {_message.id}")
    db.delete(_message)
    db.commit()
    session:LlamaIndexFunctionAgentSession = lifaSessions.get_session(chat_id=chat_id)
    messages = getMessagesByChatId(db,chat_id)
    session.reset_history(messages)
    return okResult()




@router.put("/change_chat_ai_agent", response_model=BaseResult)
def change_chat_ai_agent(
        *,
        db: Session = Depends(get_db),
        param: ChangeChatAiAgent=Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    新增消息
    """
    chat_id = param.chat_id
    chat:Chat=(db.query(Chat)
               .filter(Chat.id == chat_id)
               ).first()
    if chat is None:
        raise HTTPException(status_code=404, detail="对话不存在")

    chat.ai_agent_id=param.ai_agent_id
    db.add(chat)
    db.commit()
    db.refresh(chat)
    data=AIService.get_ai_agent_view_info(db,param.ai_agent_id)[0]
    result={
        "ai_agent_id": param.ai_agent_id,
        "vDesc":data
    }
    return okResult(data=result).json_encoders()

